﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using NetJsWire.Lite.Converters;
using NetJsWire.Lite.Editors;
using Newtonsoft.Json;

namespace NetJsWire.Lite.Widgets.UI.Grid
{
    /// <summary>
    ///   /**
    ///   <p>A Grid column type which renders an icon, or a series of icons in a grid cell, and offers a scoped click
    ///     handler for each icon. Example usage:</p>
    ///   <pre><code>
    ///          new Ext.grid.GridPanel({
    ///          store: myStore,
    ///          columns: [
    ///          {
    ///          xtype: 'actioncolumn',
    ///          width: 50,
    ///          items: [
    ///          {
    ///          icon   : 'sell.gif',                // Use a URL in the icon config
    ///          tooltip: 'Sell stock',
    ///          handler: function(grid, rowIndex, colIndex) {
    ///          var rec = store.getAt(rowIndex);
    ///          alert("Sell " + rec.get('company'));
    ///          }
    ///          },
    ///          {
    ///          getClass: function(v, meta, rec) {  // Or return a class from a function
    ///          if (rec.get('change') < 0) {
    ///     this.items[1].tooltip = 'Do not buy!';
    ///    return 'alert-col';
    ///     } else {
    ///    this.items[1].tooltip = 'Buy stock';
    ///    return 'buy-col';
    ///     }
    ///     },
    ///    handler: function(grid, rowIndex, colIndex) {
    ///    var rec =  store.getAt(rowIndex);
    ///    alert("Buy " + rec.get('company'));
    ///     }
    ///     }
    ///     ]
    ///     }
    ///     //any other columns here
    ///     ]
    ///     });
    ///   </pre></code>
    ///   <p>The action column can be at any index in the columns array, and a grid can have any number of
    ///     action columns. </p>
    ///   */
    ///   Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, {
    /// </summary>
    [Serializable]
    [JsonObject( MemberSerialization = MemberSerialization.OptOut )]
    public class ActionColumn : Column
    {
        internal ActionColumn()
            : this( null )
        {
        }

        public ActionColumn( ColumnModel model )
            : base( model )
        {
            Xtype = "actioncolumn";
            Items = new ActionColumnItemCollection();
        }

        /// <summary>
        ///   The URL of an image to display as the clickable element in the column.
        ///   Optional - defaults to <code>{@link Ext#BLANK_IMAGE_URL Ext.BLANK_IMAGE_URL}</code>.
        /// </summary>
        [JsonProperty( "icon" )]
        [DefaultValue( ( string ) null )]
        public string Icon { get; set; }

        /// <summary>
        ///   A CSS class to apply to the icon image. To determine the class dynamically, configure the Column with a <code>{@link #getClass}</code> function.
        /// </summary>
        [JsonProperty( "iconCls" )]
        [DefaultValue( ( string ) null )]
        public string IconCls { get; set; }

        /// <summary>
        ///   A function called when the icon is clicked.The handler is passed the following parameters:<div class = "mdetail-params"><ul>
        ///                                                                                                                             <li><code>grid</code> : GridPanel<div class = "sub-desc">The owning GridPanel.</div></li>
        ///                                                                                                                             <li><code>rowIndex</code> : Number<div class = "sub-desc">The row index clicked on.</div></li>
        ///                                                                                                                             <li><code>colIndex</code> : Number<div class = "sub-desc">The column index clicked on.</div></li>
        ///                                                                                                                             <li><code>item</code> : Object<div class = "sub-desc">The clicked item (or this Column if multiple
        ///                                                                                                                                                             {@link #items} were not configured).</div></li>
        ///                                                                                                                             <li><code>e</code> : Event<div class = "sub-desc">The click event.</div></li>
        ///                                                                                                                           </ul></div>
        /// </summary>
        [JsonProperty( "handler" )]
        [JsonConverter( typeof( NotQuotedJsonStringConverter ) )]
        [DefaultValue( ( string ) null )]
        [Editor( typeof( ScriptEditor ), typeof( UITypeEditor ) )]
        public string Handler { get; set; }

        /// <summary>
        ///   Defaults to <code>true</code>. Prevent grid <i>row</i> selection upon mousedown.
        /// </summary>
        [JsonProperty( "stopSelection" )]
        [DefaultValue( false )]
        public bool StopSelection { get; set; }

        /// <summary>
        ///   A function which returns the CSS class to apply to the icon image.The function is passed the following parameters:<ul>
        ///                                                                                                                       <li><b>v</b> : Object<p class = "sub-desc">The value of the column's configured field (if any).</p></li>
        ///                                                                                                                       <li><b>metadata</b> : Object<p class = "sub-desc">An object in which you may set the following attributes:<ul>
        ///                                                                                                                                                                                                                                   <li><b>css</b> : String<p class = "sub-desc">A CSS class name to add to the cell's TD element.</p></li>
        ///                                                                                                                                                                                                                                   <li><b>attr</b> : String<p class = "sub-desc">An HTML attribute definition string to apply to the data container element <i>within</i> the table cell
        ///                                                                                                                                                                                                                                                             (e.g. 'style="color:red;"').</p></li>
        ///                                                                                                                                                                                                                                 </ul></p></li>
        ///                                                                                                                       <li><b>r</b> : Ext.data.Record<p class = "sub-desc">The Record providing the data.</p></li>
        ///                                                                                                                       <li><b>rowIndex</b> : Number<p class = "sub-desc">The row index..</p></li>
        ///                                                                                                                       <li><b>colIndex</b> : Number<p class = "sub-desc">The column index.</p></li>
        ///                                                                                                                       <li><b>store</b> : Ext.data.Store<p class = "sub-desc">The Store which is providing the data Model.</p></li>
        ///                                                                                                                     </ul>
        /// </summary>
        [JsonProperty( "getClass" )]
        [JsonConverter( typeof( NotQuotedJsonStringConverter ) )]
        [DefaultValue( ( string ) null )]
        [Editor( typeof( ScriptEditor ), typeof( UITypeEditor ) )]
        public string GetClass { get; set; }

        /// <summary>
        ///   An Array which may contain multiple icon definitions, each element of which may contain:<div class = "mdetail-params"><ul>
        ///                                                                                                                           <li><code>icon</code> : String<div class = "sub-desc">The url of an image to display as the clickable element
        ///                                                                                                                                                           in the column.</div></li>
        ///                                                                                                                           <li><code>iconCls</code> : String<div class = "sub-desc">A CSS class to apply to the icon image.
        ///                                                                                                                                                              To determine the class dynamically, configure the item with a <code>getClass</code> function.</div></li>
        ///                                                                                                                           <li><code>getClass</code> : Function<div class = "sub-desc">A function which returns the CSS class to apply to the icon image.
        ///                                                                                                                                                                 The function is passed the following parameters:<ul>
        ///                                                                                                                                                                                                                   <li><b>v</b> : Object<p class = "sub-desc">The value of the column's configured field (if any).</p></li>
        ///                                                                                                                                                                                                                   <li><b>metadata</b> : Object<p class = "sub-desc">An object in which you may set the following attributes:<ul>
        ///                                                                                                                                                                                                                                                                                                                               <li><b>css</b> : String<p class = "sub-desc">A CSS class name to add to the cell's TD element.</p></li>
        ///                                                                                                                                                                                                                                                                                                                               <li><b>attr</b> : String<p class = "sub-desc">An HTML attribute definition string to apply to the data container element <i>within</i> the table cell
        ///                                                                                                                                                                                                                                                                                                                                                         (e.g. 'style="color:red;"').</p></li>
        ///                                                                                                                                                                                                                                                                                                                             </ul></p></li>
        ///                                                                                                                                                                                                                   <li><b>r</b> : Ext.data.Record<p class = "sub-desc">The Record providing the data.</p></li>
        ///                                                                                                                                                                                                                   <li><b>rowIndex</b> : Number<p class = "sub-desc">The row index..</p></li>
        ///                                                                                                                                                                                                                   <li><b>colIndex</b> : Number<p class = "sub-desc">The column index.</p></li>
        ///                                                                                                                                                                                                                   <li><b>store</b> : Ext.data.Store<p class = "sub-desc">The Store which is providing the data Model.</p></li>
        ///                                                                                                                                                                                                                 </ul></div></li>
        ///                                                                                                                           <li><code>handler</code> : Function<div class = "sub-desc">A function called when the icon is clicked.</div></li>
        ///                                                                                                                           <li><code>scope</code> : Scope<div class = "sub-desc">The scope (<code><b>this</b></code> reference) in which the
        ///                                                                                                                                                           <code>handler</code> and <code>getClass</code> functions are executed. Fallback defaults are this Column's
        ///                                                                                                                                                           configured scope, then this Column.</div></li>
        ///                                                                                                                           <li><code>tooltip</code> : String<div class = "sub-desc">A tooltip message to be displayed on hover.
        ///                                                                                                                                                              {@link Ext.QuickTips#init Ext.QuickTips} must have been initialized.</div></li>
        ///                                                                                                                         </ul></div>
        /// </summary>
        [JsonProperty( "items" )]
        public ActionColumnItemCollection Items { get; private set; }

        /// <summary>
        ///   The alt text to use for the image element. Defaults to <tt>''</tt>.
        /// </summary>
        [JsonProperty( "altText" )]
        [DefaultValue( ( string ) null )]
        public string AltText { get; set; }

        public bool ShouldSerializeItems()
        {
            return Items != null && Items.Count > 0;
        }

        protected void ResetItems()
        {
            Items.Clear();
        }
    }

    [Serializable]
    [JsonObject( MemberSerialization = MemberSerialization.OptOut )]
    public class ActionColumnItem
    {
        [JsonProperty( "icon" )]
        [DefaultValue( ( string ) null )]
        [Description( "The url of an image to display as the clickable element in the column." )]
        public string Icon { get; set; }

        /// <summary>
        ///   A CSS class to apply to the icon image. To determine the class dynamically, configure the Column with a <code>{@link #getClass}</code> function.
        /// </summary>
        [JsonProperty( "iconCls" )]
        [DefaultValue( ( string ) null )]
        public string IconCls { get; set; }

        /// <summary>
        ///   A function which returns the CSS class to apply to the icon image.The function is passed the following parameters:<ul>
        ///                                                                                                                       <li><b>v</b> : Object<p class = "sub-desc">The value of the column's configured field (if any).</p></li>
        ///                                                                                                                       <li><b>metadata</b> : Object<p class = "sub-desc">An object in which you may set the following attributes:<ul>
        ///                                                                                                                                                                                                                                   <li><b>css</b> : String<p class = "sub-desc">A CSS class name to add to the cell's TD element.</p></li>
        ///                                                                                                                                                                                                                                   <li><b>attr</b> : String<p class = "sub-desc">An HTML attribute definition string to apply to the data container element <i>within</i> the table cell
        ///                                                                                                                                                                                                                                                             (e.g. 'style="color:red;"').</p></li>
        ///                                                                                                                                                                                                                                 </ul></p></li>
        ///                                                                                                                       <li><b>r</b> : Ext.data.Record<p class = "sub-desc">The Record providing the data.</p></li>
        ///                                                                                                                       <li><b>rowIndex</b> : Number<p class = "sub-desc">The row index..</p></li>
        ///                                                                                                                       <li><b>colIndex</b> : Number<p class = "sub-desc">The column index.</p></li>
        ///                                                                                                                       <li><b>store</b> : Ext.data.Store<p class = "sub-desc">The Store which is providing the data Model.</p></li>
        ///                                                                                                                     </ul>
        /// </summary>
        [JsonProperty( "getClass" )]
        [JsonConverter( typeof( NotQuotedJsonStringConverter ) )]
        [DefaultValue( ( string ) null )]
        [Editor( typeof( ScriptEditor ), typeof( UITypeEditor ) )]
        public string GetClass { get; set; }

        /// <summary>
        ///   A function called when the icon is clicked.The handler is passed the following parameters:<div class = "mdetail-params"><ul>
        ///                                                                                                                             <li><code>grid</code> : GridPanel<div class = "sub-desc">The owning GridPanel.</div></li>
        ///                                                                                                                             <li><code>rowIndex</code> : Number<div class = "sub-desc">The row index clicked on.</div></li>
        ///                                                                                                                             <li><code>colIndex</code> : Number<div class = "sub-desc">The column index clicked on.</div></li>
        ///                                                                                                                             <li><code>item</code> : Object<div class = "sub-desc">The clicked item (or this Column if multiple
        ///                                                                                                                                                             {@link #items} were not configured).</div></li>
        ///                                                                                                                             <li><code>e</code> : Event<div class = "sub-desc">The click event.</div></li>
        ///                                                                                                                           </ul></div>
        /// </summary>
        [JsonProperty( "handler" )]
        [JsonConverter( typeof( NotQuotedJsonStringConverter ) )]
        [DefaultValue( ( string ) null )]
        [Editor( typeof( ScriptEditor ), typeof( UITypeEditor ) )]
        public string Handler { get; set; }

        /// <summary>
        ///   Defaults to <code>true</code>. Prevent grid <i>row</i> selection upon mousedown.
        /// </summary>
        [JsonProperty( "stopSelection" )]
        [DefaultValue( false )]
        public bool StopSelection { get; set; }

        [DefaultValue( ( string ) null )]
        [JsonConverter( typeof( NotQuotedJsonStringConverter ) )]
        [JsonProperty( "scope" )]
        public string Scope { get; set; }

        [DefaultValue( ( string ) null )]
        [JsonProperty( "tooltip" )]
        public string Tooltip { get; set; }
    }

    [Serializable]
    public class ActionColumnItemCollection : List<ActionColumnItem>
    {
        public void AddRange( params ActionColumnItem[] items )
        {
            if ( items == null )
                return;
            foreach ( var item in items )
            {
                Add( item );
            }
        }
    }
}